#ifndef ___fat32_subtransaccion12_obtener_atributos

#define ___fat32_subtransaccion12_obtener_atributos 1

#include "f32_mto.c"

#include "f32_datr.c"

#include "f32_opAL.c"
#include "f32_opAM.c"
#include "f32_opAN.c"
#include "f32_opAP.c"
#include "f32_opAT.c"
#include "f32_opAU.c"

struct fat32st12_datos {
  unsigned long clusterInicio;
  unsigned short numeroEntrada;
  unsigned int conexion;
  unsigned long * cadena;
  unsigned long sectorActual;
  char entrada[32];
  char buffer[2048];
  unsigned short posicionBuffer;
  unsigned long sectorReal;
  unsigned char entradaReal;
  struct fat32_atributos_archivo * atrib;
};

unsigned char fat32st_obtener_atributos(unsigned char, unsigned int, unsigned long, unsigned short, void **, unsigned char, void *);

unsigned char fat32st_obtener_atributos (unsigned char estado, unsigned int transaccion, unsigned long clusterInicioDirectorio,
                                         unsigned short numeroEntradaPrincipal, void ** datos, unsigned char estadoOp, void * datosOp) {
  struct fat32st12_datos * datosST = *datos;
  switch (estado) {
  case 0:
    *datos = malloc(sizeof(struct fat32st12_datos));
    datosST = *datos;
    datosST -> clusterInicio = clusterInicioDirectorio;
    datosST -> numeroEntrada = numeroEntradaPrincipal;
    datosST -> conexion = fat32_obtener_conexion_para_transaccion(transaccion);
    fat32_crear_operacion(transaccion, &fat32op_obtener_cadena_clusteres, &(datosST -> clusterInicio), sizeof(unsigned long));
    return 1;
  case 1:
    datosST -> cadena = datosOp;
    fat32_quitar_operacion(transaccion);
    unsigned short numSector = (datosST -> numeroEntrada) / 16;
    struct fat32_posicion_sector pos = fat32_obtener_posicion_sector(numSector, 1);
    pos.cluster = (datosST -> cadena)[pos.cluster];
    free(datosST -> cadena);
    datosST -> sectorReal = fat32_obtener_sector_lineal(pos, 0);
    datosST -> entradaReal = numEntrada % 16;
    return 2;
  case 2:
    struct fat32opAM_solicitud_bloque ds;
    datosST -> posicionBuffer = 512 * ((datosST -> sectorReal) % 4) + 32 * (datosST -> entradaReal);
    datosST -> sectorReal &= ~3L;
    ds.sector = datosST -> sectorReal;
    ds.conexion = datosST -> conexion;
    ds.buffer = datosST -> buffer;
    fat32_crear_operacion(transaccion, &fat32op_solicitar_bloque, &ds, sizeof ds);
    return 3;
  case 3:
    fat32_quitar_operacion(transaccion);
    return 4;
  case 4:
    memcpy(datosST -> entrada, (datosST -> buffer) + (datosST -> posicionBuffer), 32);
    fat32_crear_operacion(transaccion, &fat32op_procesar_entrada_directorio, datosST -> entrada, 32);
    return 5;
  case 5:
    datosST -> atrib = datosOp;
    fat32_quitar_operacion(transaccion);
    if (estadoOp == 1) {
      *datos = datosST -> atrib;
      free(datosST);
      return 0;
    }
    return 6;
  case 6:
    fat32_crear_operacion(transaccion, &fat32op_obtener_cluster_inicio_archivo, datosST -> entrada, 32);
    return 7;
  case 7:
    datosST -> cadena = datosOp;
    fat32_quitar_operacion(transaccion);
    unsigned long longitudC = 0;
    while ((datosST -> cadena)[longitudC]) longitudC ++;
    fat32_crear_operacion(transaccion, &fat32op_obtener_cadena_sectores_desde_clusteres, datosST -> cadena, 
                                                                     (1 + longitud) * sizeof(unsigned long));
    free(datosST -> cadena);
    return 8;
  case 8:
    datosST -> cadena = datosOp;
    fat32_quitar_operacion(transaccion);
    datosST -> sectorActual = 0;
    datosST -> atrib -> hardlinks = 2;
    return 9;
  case 9:
    datosST -> sectorReal = (datosST -> cadena)[datosST -> sectorActual];
    if (!(datosST -> sectorReal)) return 10;
    datosST -> posicionBuffer = ((datosST -> sectorReal) & 3) * 512;
    datosST -> sectorReal &= ~3L;
    struct fat32opAM_solicitud_bloque ss;
    ss.sector = datosST -> sectorReal;
    ss.conexion = datosST -> conexion;
    ss.buffer = datosST -> buffer;
    fat32_crear_operacion(transaccion, &fat32op_solicitar_bloque, &ss, sizeof ss);
    return 11;
  case 10:
    free(datosST -> cadena);
    *datos = datosST -> atrib;
    free(datosST);
    return 0;
  case 11:
    fat32_quitar_operacion(transaccion);
    char * ptrSector = datosST -> buffer;
    ptrSector += datosST -> sectorReal;
    fat32_crear_operacion(transaccion, &fat32op_contar_entradas_en_sector_de_directorio, ptrSector, 512);
    return 12;
  case 12:
    unsigned char * th = datosOp;
    datosST -> atrib -> hardlinks += *th;
    fat32_quitar_operacion(transaccion);
    if (estadoOp == 2) return 10;
    datosST -> sectorActual ++;
    return 9;
  }
}

#endif